package pers.mor.tomcat.catalina;

import cn.hutool.core.date.TimeInterval;
import cn.hutool.log.LogFactory;
import cn.hutool.system.SystemUtil;

import pers.mor.tomcat.config.ContextXML;
import pers.mor.tomcat.config.ServerXML;
import pers.mor.tomcat.config.WebXML;

import pers.mor.tomcat.exception.ServerRuntimeException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Server {

    private static Long time = 0L;
    private static Integer serviceNumber = 0;
    private int count = 0;
    private static List<Service> serviceList;

    private Server() {
        synchronized (Server.class) {
            if(count > 0){
                throw new ServerRuntimeException("Server class must be a single pattern");
            }
            count++;
        }
        this.serviceList = new ArrayList<>();
    }

    private void start() {
        logJVM();
        ContextXML.initWebInf();
        ServerXML.builderServer(this);
        WebXML.initMimeTypeMap();
        this.init();
    }

    private void init() {
        for (Service s : this.serviceList) {
            s.start();
        }
    }

    private static void logJVM() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Map<String,String> infos = new LinkedHashMap<>();
        infos.put("Server version", "JerryMouse/1.0.1");
        infos.put("Server built", dateFormat.format(new Date()));
        infos.put("Server number", "1.0.1");
        infos.put("OS Name\t", SystemUtil.get("os.name"));
        infos.put("OS Version", SystemUtil.get("os.version"));
        infos.put("Architecture", SystemUtil.get("os.arch"));
        infos.put("Java Home", SystemUtil.get("java.home"));
        infos.put("JVM Version", SystemUtil.get("java.runtime.version"));
        infos.put("JVM Vendor", SystemUtil.get("java.vm.specification.vendor"));

        /**
         * Hutool默认会使用JDK Logging做为其日志实现，默认会到项目根目录的src目录中查找日志配置文件。
         * 底层调用new Thread().getContextClassLoader().getResource("");(""返回根目录)查找日志配置文件
         * hutool的LogFactory.get()会自动识别当前类，将当前类做为类名传入日志框架。
         * 不需要private static final Logger log = LoggerFactory.getLogger(XXX.class);
         */
        Set<String> keys = infos.keySet();
        for (String key : keys) {
            LogFactory.get().info(key+":\t\t" + infos.get(key));
        }
    }

    public List<Service> getServiceList() {
        return this.serviceList;
    }

    public static Service getService(String port) {
        for (Service service : serviceList) {
            List<Integer> portList = service.getPortList();
            for (Integer p : portList) {
                if (p == Integer.parseInt(port)) {
                    return service;
                }
            }
        }
        return null;
    }

    public static void serviceNum(int n) {
        serviceNumber = serviceNumber + n;
    }

    public static void elapsedTime(TimeInterval t) {
        time = time + t.intervalMs();
        if (serviceList.size() == serviceNumber) {
            LogFactory.get().info("Server startup in {} ms", time);
        }
    }

}
